#include "lcd.h"
#include "delay.h"
#include <reg51.h>
/*******************************************************************************
* 函 数 名         : write_com
* 函数功能		   : 写入一个命令到12864
* 输    入         : com
* 输    出         : 无
*******************************************************************************/

void write_com(uchar com)
{
	lcdcs=0;//打开片选
	lcdrd=1;//读失能
	lcdrs=0;//选择命令
	
	P0=com;//放置命令
	
	lcdrw=0; //选择写模式
	delay(1);
	lcdrw=1;//写入命令
    delay(1);	
	
}
/*******************************************************************************
* 函 数 名         : write_data
* 函数功能		   : 写入一个数据到12864
* 输    入         : data
* 输    出         : 无
* 输入方式         ：从左到右从上到下取数据区间，纵向8点下高位
*******************************************************************************/

void write_data(uchar date)
{
	lcdcs=0;//打开片选
	lcdrd=1;//读失能
	lcdrs=1;//选择数据
	lcdrw=0;//选择写模式
	
	P0=date;//放置数据
	
	lcdrw=0;//选择写模式
	delay(1);
	lcdrw=1;//写数据
    delay(1);
}
/*******************************************************************************
* 函 数 名         : init
* 函数功能		   : 初始化12864
* 输    入         : 无
* 输    出         : 无
* 说    明         : LCD12864的命令指令可以查看例程文件夹下的《ST7565p数据手册》
*                  * 的第51页的位置。
*******************************************************************************/

void init()
{
  uchar i;
	reset = 0;
	for (i=0; i<100; i++);
	lcdcs = 0;
	reset = 1;
	
	//----------------Star Initial Sequence-------//
	//------程序初始化设置，具体命令可以看文件夹下---//

	//--软件初始化--//
	write_com(0xE2);  //reset
	for (i=0; i<100; i++);	   //延时一下

	//--表格第8个命令，0xA0段（左右）方向选择正常方向（0xA1为反方向）--//
	write_com(0xA0);  //ADC select segment direction 
	
	//--表格第15个命令，0xC8普通(上下)方向选择选择反向，0xC0为正常方向--// 
	write_com(0xC8);  //Common direction 
	                  
	//--表格第9个命令，0xA6为设置字体为黑色，背景为白色---//
	//--0xA7为设置字体为白色，背景为黑色---//
	write_com(0xA6);  //reverse display

	//--表格第10个命令，0xA4像素正常显示，0xA5像素全开--//
	write_com(0xA4);  //normal display
	
	//--表格第11个命令，0xA3偏压为1/7,0xA2偏压为1/9--//
	write_com(0xA2);  //bias set 1/9
	
	//--表格第19个命令，这个是个双字节的命令，0xF800选择增压为4X;--//
	//--0xF801,选择增压为5X，其实效果差不多--//	
	write_com(0xF8);  //Boost ratio set
	write_com(0x01);  //x4
	
	//--表格第18个命令，这个是个双字节命令，高字节为0X81，低字节可以--//
	//--选择从0x00到0X3F。用来设置背景光对比度。---/
	write_com(0x81);  //V0 a set
	write_com(0x23);

	//--表格第17个命令，选择调节电阻率--//
	write_com(0x25);  //Ra/Rb set
	
	//--表格第16个命令，电源设置。--//
	write_com(0x2F);
	for (i=0; i<100; i++);

	//--表格第2个命令，设置显示开始位置--//
	write_com(0x40);  //start line

	//--表格第1个命令，开启显示--//
	write_com(0xAF);  // display on
	for (i=0; i<100; i++);

}
/*******************************************************************************
* 函 数 名         : clean
* 函数功能		   : 清屏12864
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

void clean()
{
	uchar i, j;

	for(i=0; i<9; i++)
	{
		//--表格第3个命令，设置Y的坐标--//
		//--Y轴有64个，一个坐标8位，也就是有8个坐标--//
		//所以一般我们使用的也就是从0xB0到0x07,就够了--//	
		write_com(0xB0+i); 

		//--表格第4个命令，设置X坐标--//
		//--当你的段初始化为0xA1时，X坐标从0x10,0x04到0x18,0x04,一共128位--//
		//--当你的段初始化为0xA0时，X坐标从0x10,0x00到0x18,0x00,一共128位--//
		//--在写入数据之后X坐标的坐标是会自动加1的，我们初始化使用0xA0所以--//
		//--我们的X坐标从0x10,0x00开始---//
		write_com(0x10); 
		write_com(0x00);
        	
    	
		
		//--X轴有128位，就一共刷128次，X坐标会自动加1，所以我们不用再设置坐标--//
		for(j=0; j<128; j++)
		{
			write_data(0x00);  //如果设置背景为白色时，清屏选择0XFF
		}
	}
}
/*******************************************************************************
* 函 数 名         : char_swap
* 函数功能		   : 八位字符颠倒，1100 0111变为1110 0011
* 输    入         : dat。
* 输    出         : num
* 作用            : 为适应取模软件而写
*******************************************************************************/

uchar char_swap(uchar dat)
{
	uchar i,num=0;
	for(i=0;i<8;i++)
	    num=(num<<1)+(dat>>i&1);
	return num;
}
/*******************************************************************************
* 函 数 名         : write_char
* 函数功能		   : 写入16x16点阵字符(汉字)
* 输    入         : x，y，*data。
* 输    出         : 无
* 取模             : 从左到右，从上到下，纵向8点上高位。
*******************************************************************************/	
void write_char(uchar x,uchar y,uchar *dat)
{
	uchar i;
	
	write_com(0xB0+2*(y-1));  //y坐标
	write_com(0x10+(x-1));   //x坐标的高4位
    write_com(0x00+0);   //x坐标的低4位	
	for(i=0;i<16;i++)
	    write_data(char_swap(dat[i]));	
	
	
	write_com(0xB0+2*(y-1)+1);
	write_com(0x10+(x-1)); 
    write_com(0x00+0);
	for(i=0;i<16;i++)
	    write_data(char_swap(dat[16+i]));	

}
/*******************************************************************************
* 函 数 名         : write_smchar
* 函数功能		   : 写入16x8点阵字符(数字及字母）
* 输    入         : x，y，*data。
* 输    出         : 无
* 取模             : 从左到右，从上到下，纵向8点上高位。
*******************************************************************************/
void write_smchar(uchar x,uchar y,uchar *dat)
{
	uchar i;
	
	write_com(0xB0+(y-1));  //y坐标
	write_com(0x10+(x-1));   //x坐标的高4位
    write_com(0x00+0);   //x坐标的低4位	
	for(i=0;i<8;i++)
	    write_data(char_swap(dat[i]));	
	
	
	write_com(0xB0+(y-1)+1);
	write_com(0x10+(x-1)); 
    write_com(0x00+0);
	for(i=0;i<8;i++)
	    write_data(char_swap(dat[8+i]));	

}
